﻿#include "Settings.h"
#include "../Shared/Language.h"
#include "../Shared/Data/Stat.h"
#include "../Shared/Enums.h"

using namespace Server::MirDatabase;
using namespace Server::MirObjects;

namespace Server
{

long long Settings::GroupInviteDelay = 2000;
long long Settings::TradeDelay = 2000;

    Server::MessageQueue *Settings::getMessageQueue()
    {
        return MessageQueue::getInstance();
    }

const std::string Settings::EnvirPath = FileSystem::combine(".", "Envir");
const std::string Settings::ConfigPath = FileSystem::combine(".", "Configs");
const std::string Settings::MapPath = FileSystem::combine(".", "Maps");
const std::string Settings::ExportPath = FileSystem::combine(".", "Exports");
const std::string Settings::GuildPath = FileSystem::combine(".", "Guilds");
const std::string Settings::ConquestsPath = FileSystem::combine(".", "Conquests");
const std::string Settings::NPCPath = FileSystem::combine(EnvirPath, "NPCs");
const std::string Settings::GoodsPath = FileSystem::combine(EnvirPath, "Goods");
const std::string Settings::RecipePath = FileSystem::combine(EnvirPath, "Recipe");
const std::string Settings::QuestPath = FileSystem::combine(EnvirPath, "Quests");
const std::string Settings::DropPath = FileSystem::combine(EnvirPath, "Drops");
const std::string Settings::RoutePath = FileSystem::combine(EnvirPath, "Routes");
const std::string Settings::NameListPath = FileSystem::combine(EnvirPath, "NameLists");
const std::string Settings::ValuePath = FileSystem::combine(EnvirPath, "Values");
const std::string Settings::NoticePath = FileSystem::combine(EnvirPath, "Notice.txt");
InIReader *const Settings::Reader = new InIReader(FileSystem::combine(ConfigPath, "Setup.ini"));
Settings::Notice *Notice;
std::string Settings::VersionPath = FileSystem::combine(".", "Mir2.Exe");
bool Settings::CheckVersion = true;
std::vector<std::vector<unsigned char>> Settings::VersionHashes;
std::string Settings::GMPassword = "C#Mir 4.0";
bool Settings::Multithreaded = true;
int Settings::ThreadLimit = 2;
bool Settings::TestServer = false;
bool Settings::EnforceDBChecks = true;
bool Settings::MonsterProcessWhenAlone = false;
bool Settings::MonsterProcessWhenStacked = false;
std::string Settings::DefaultNPCFilename = "00Default";
std::string Settings::MonsterNPCFilename = "00Monster";
std::string Settings::RobotNPCFilename = "00Robot";
std::string Settings::FishingDropFilename = "00Fishing";
std::string Settings::AwakeningDropFilename = "00Awakening";
std::string Settings::StrongboxDropFilename = "00Strongbox";
std::string Settings::BlackstoneDropFilename = "00Blackstone";
std::string Settings::IPAddress = "127.0.0.1";
unsigned short Settings::Port = 7000;
unsigned short Settings::TimeOut = 10000;
unsigned short Settings::MaxUser = 50;
unsigned short Settings::RelogDelay = 50;
unsigned short Settings::MaxIP = 5;
bool Settings::StartHTTPService = false;
std::string Settings::HTTPIPAddress = "http://127.0.0.1:5679/";
std::string Settings::HTTPTrustedIPAddress = "127.0.0.1";
bool Settings::AllowNewAccount = true;
bool Settings::AllowChangePassword = true;
bool Settings::AllowLogin = true;
bool Settings::AllowNewCharacter = true;
bool Settings::AllowDeleteCharacter = true;
bool Settings::AllowStartGame = false;
bool Settings::AllowCreateAssassin = true;
bool Settings::AllowCreateArcher = true;
int Settings::AllowedResolution = 1024;
bool Settings::SafeZoneBorder = false;
bool Settings::SafeZoneHealing = false;
bool Settings::GameMasterEffect = false;
bool Settings::GatherOrbsPerLevel = true;
bool Settings::ExpMobLevelDifference = true;
int Settings::LineMessageTimer = 10;
int Settings::SaveDelay = 5;
short Settings::CredxGold = 30;
std::vector<long long> Settings::ExperienceList;
std::vector<long long> Settings::OrbsExpList;
std::vector<long long> Settings::OrbsDefList;
std::vector<long long> Settings::OrbsDmgList;
float Settings::DropRate = 1.0F;
float Settings::ExpRate = 1.0F;
int Settings::ItemTimeOut = 30;
int Settings::PlayerDiedItemTimeOut = 120;
int Settings::DropRange = 4;
int Settings::DropStackSize = 5;
int Settings::PKDelay = 12;
bool Settings::PetSave = false;
int Settings::RestedPeriod = 60;
int Settings::RestedBuffLength = 10;
int Settings::RestedExpBonus = 5;
int Settings::RestedMaxBonus = 24;
std::string Settings::SkeletonName = "BoneFamiliar";
std::string Settings::ShinsuName = "Shinsu";
std::string Settings::BugBatName = "BugBat";
std::string Settings::Zuma1 = "ZumaStatue";
std::string Settings::Zuma2 = "ZumaGuardian";
std::string Settings::Zuma3 = "ZumaArcher";
std::string Settings::Zuma4 = "WedgeMoth";
std::string Settings::Zuma5 = "ZumaArcher3";
std::string Settings::Zuma6 = "ZumaStatue3";
std::string Settings::Zuma7 = "ZumaGuardian3";
std::string Settings::Turtle1 = "RedTurtle";
std::string Settings::Turtle2 = "GreenTurtle";
std::string Settings::Turtle3 = "BlueTurtle";
std::string Settings::Turtle4 = "TowerTurtle";
std::string Settings::Turtle5 = "FinialTurtle";
std::string Settings::BoneMonster1 = "BoneSpearman";
std::string Settings::BoneMonster2 = "BoneBlademan";
std::string Settings::BoneMonster3 = "BoneArcher";
std::string Settings::BoneMonster4 = "BoneCaptain";
std::string Settings::BehemothMonster1 = "Hugger";
std::string Settings::BehemothMonster2 = "PoisonHugger";
std::string Settings::BehemothMonster3 = "MutatedHugger";
std::string Settings::HellKnight1 = "HellKnight1";
std::string Settings::HellKnight2 = "HellKnight2";
std::string Settings::HellKnight3 = "HellKnight3";
std::string Settings::HellKnight4 = "HellKnight4";
std::string Settings::HellBomb1 = "HellBomb1";
std::string Settings::HellBomb2 = "HellBomb2";
std::string Settings::HellBomb3 = "HellBomb3";
std::string Settings::WhiteSnake = "WhiteSerpent";
std::string Settings::AngelName = "HolyDeva";
std::string Settings::BombSpiderName = "BombSpider";
std::string Settings::CloneName = "Clone";
std::string Settings::AssassinCloneName = "AssassinClone";
std::string Settings::VampireName = "VampireSpider";
std::string Settings::ToadName = "SpittingToad";
std::string Settings::SnakeTotemName = "SnakeTotem";
std::string Settings::SnakesName = "CharmedSnake";
std::string Settings::AncientBatName = "AncientBat";
std::string Settings::TucsonGeneralEgg = "GeneralTucson";
std::string Settings::GeneralMeowMeowMob1 = "StainHammerCat";
std::string Settings::GeneralMeowMeowMob2 = "BlackHammerCat";
std::string Settings::GeneralMeowMeowMob3 = "StrayCat";
std::string Settings::GeneralMeowMeowMob4 = "CatShaman";
std::string Settings::HealRing = "Healing";
std::string Settings::FireRing = "FireBall";
std::string Settings::ParalysisRing = "Paralysis";
std::string Settings::BlinkSkill = "Blink";
std::string Settings::PKTownMapName = "3";
int Settings::PKTownPositionX = 848;
int Settings::PKTownPositionY = 677;
unsigned int Settings::MaxDropGold = 2000;
bool Settings::DropGold = true;
std::string Settings::CreatureBlackStoneName = "BlackCreatureStone";
int Settings::FishingAttempts = 30;
int Settings::FishingSuccessStart = 10;
int Settings::FishingSuccessMultiplier = 10;
long long Settings::FishingDelay = 0;
int Settings::FishingMobSpawnChance = 5;
std::string Settings::FishingMonster = "GiantKeratoid";
bool Settings::MailAutoSendGold = false;
bool Settings::MailAutoSendItems = false;
bool Settings::MailFreeWithStamp = true;
unsigned int Settings::MailCostPer1KGold = 100;
unsigned int Settings::MailItemInsurancePercentage = 5;
unsigned int Settings::MailCapacity = 100;
bool Settings::OnlyRefineWeapon = true;
unsigned char Settings::RefineBaseChance = 20;
int Settings::RefineTime = 20;
unsigned char Settings::RefineIncrease = 1;
unsigned char Settings::RefineCritChance = 10;
unsigned char Settings::RefineCritIncrease = 2;
unsigned char Settings::RefineWepStatReduce = 6;
unsigned char Settings::RefineItemStatReduce = 15;
int Settings::RefineCost = 125;
std::string Settings::RefineOreName = "BlackIronOre";
int Settings::LoverEXPBonus = 5;
int Settings::MarriageCooldown = 7;
bool Settings::WeddingRingRecall = true;
int Settings::MarriageLevelRequired = 10;
int Settings::ReplaceWedRingCost = 125;
unsigned char Settings::MentorLevelGap = 10;
bool Settings::MentorSkillBoost = true;
unsigned char Settings::MentorLength = 7;
unsigned char Settings::MentorDamageBoost = 10;
unsigned char Settings::MentorExpBoost = 10;
unsigned char Settings::MenteeExpBank = 1;
bool Settings::GemStatIndependent = true;
bool Settings::GoodsOn = true;
unsigned int Settings::GoodsMaxStored = 15;
unsigned int Settings::GoodsBuyBackTime = 60;
unsigned int Settings::GoodsBuyBackMaxStored = 20;
bool Settings::GoodsHideAddedStats = true;
std::vector<BaseStats*> Settings::ClassBaseStats =
{
    new BaseStats(MirClass::Warrior),
    new BaseStats(MirClass::Wizard),
    new BaseStats(MirClass::Taoist),
    new BaseStats(MirClass::Assassin),
    new BaseStats(MirClass::Archer)
};
std::vector<RandomItemStat*> Settings::RandomItemStatsList;
std::vector<MineSet*> Settings::MineSetList;
unsigned char Settings::MagicResistWeight = 10;
unsigned char Settings::PoisonResistWeight = 10;
unsigned char Settings::CriticalRateWeight = 5;
unsigned char Settings::CriticalDamageWeight = 50;
unsigned char Settings::FreezingAttackWeight = 10;
unsigned char Settings::PoisonAttackWeight = 10;
unsigned char Settings::HealthRegenWeight = 10;
unsigned char Settings::ManaRegenWeight = 10;
unsigned char Settings::MaxLuck = 10;
bool Settings::PvpCanResistMagic = false;
bool Settings::PvpCanResistPoison = false;
bool Settings::PvpCanFreeze = false;
unsigned char Settings::RangeAccuracyBonus = 0;
unsigned char Settings::Guild_RequiredLevel = 22;
unsigned char Settings::Guild_PointPerLevel = 0;
float Settings::Guild_ExpRate = 0.01f;
unsigned int Settings::Guild_WarCost = 3000;
long long Settings::Guild_WarTime = 180;
std::vector<GuildItemVolume*> Settings::Guild_CreationCostList;
std::vector<long long> Settings::Guild_ExperienceList;
std::vector<int> Settings::Guild_MembercapList;
std::vector<GuildBuffInfo*> Settings::Guild_BuffList;

    long long Settings::getGroupInviteDelay()
    {
        return GroupInviteDelay;
    }

    void Settings::setGroupInviteDelay(long long value)
    {
        GroupInviteDelay = value;
    }

    long long Settings::getTradeDelay()
    {
        return TradeDelay;
    }

    void Settings::setTradeDelay(long long value)
    {
        TradeDelay = value;
    }

    void Settings::LoadVersion()
    {
        try
        {
            VersionHashes = std::vector<std::vector<unsigned char>>();

            auto paths = StringHelper::split(VersionPath, ',');

            for (auto path : paths)
            {
                if (FileSystem::fileExists(path))
                {
//C# TO C++ CONVERTER NOTE: The following 'using' block is replaced by its C++ equivalent:
//ORIGINAL LINE: using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                    {
                        FileStream stream = FileStream(path, FileMode::Open, FileAccess::Read);
//C# TO C++ CONVERTER NOTE: The following 'using' block is replaced by its C++ equivalent:
//ORIGINAL LINE: using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
                        {
                        MD5CryptoServiceProvider md5 = MD5CryptoServiceProvider();
                        VersionHashes.push_back(md5.ComputeHash(stream));
                        }
                    }
                }
            }
        }
        catch (const std::runtime_error &ex)
        {
            getMessageQueue()->Enqueue(ex);
        }
    }

    void Settings::Load()
    {
        //General
        VersionPath = Reader->ReadString("General", "VersionPath", VersionPath);
        CheckVersion = Reader->ReadBoolean("General", "CheckVersion", CheckVersion);
        RelogDelay = Reader->ReadUInt16("General", "RelogDelay", RelogDelay);
        GMPassword = Reader->ReadString("General", "GMPassword", GMPassword);
        Multithreaded = Reader->ReadBoolean("General", "Multithreaded", Multithreaded);
        ThreadLimit = Reader->ReadInt32("General", "ThreadLimit", ThreadLimit);
        TestServer = Reader->ReadBoolean("General", "TestServer", TestServer);
        EnforceDBChecks = Reader->ReadBoolean("General", "EnforceDBChecks", EnforceDBChecks);
        MonsterProcessWhenAlone = Reader->ReadBoolean("General", "MonsterProcessWhenAlone", MonsterProcessWhenAlone);
        MonsterProcessWhenStacked = Reader->ReadBoolean("General", "MonsterProcessWhenStacked", MonsterProcessWhenStacked);

        //Paths
        IPAddress = Reader->ReadString("Network", "IPAddress", IPAddress);
        Port = Reader->ReadUInt16("Network", "Port", Port);
        TimeOut = Reader->ReadUInt16("Network", "TimeOut", TimeOut);
        MaxUser = Reader->ReadUInt16("Network", "MaxUser", MaxUser);
        MaxIP = Reader->ReadUInt16("Network", "MaxIP", MaxIP);

        //HTTP
        StartHTTPService = Reader->ReadBoolean("Network", "StartHTTPService", StartHTTPService);
        HTTPIPAddress = Reader->ReadString("Network", "HTTPIPAddress", HTTPIPAddress);
        HTTPTrustedIPAddress = Reader->ReadString("Network", "HTTPTrustedIPAddress", HTTPTrustedIPAddress);

        //Permission
        AllowNewAccount = Reader->ReadBoolean("Permission", "AllowNewAccount", AllowNewAccount);
        AllowChangePassword = Reader->ReadBoolean("Permission", "AllowChangePassword", AllowChangePassword);
        AllowLogin = Reader->ReadBoolean("Permission", "AllowLogin", AllowLogin);
        AllowNewCharacter = Reader->ReadBoolean("Permission", "AllowNewCharacter", AllowNewCharacter);
        AllowDeleteCharacter = Reader->ReadBoolean("Permission", "AllowDeleteCharacter", AllowDeleteCharacter);
        AllowStartGame = Reader->ReadBoolean("Permission", "AllowStartGame", AllowStartGame);
        AllowCreateAssassin = Reader->ReadBoolean("Permission", "AllowCreateAssassin", AllowCreateAssassin);
        AllowCreateArcher = Reader->ReadBoolean("Permission", "AllowCreateArcher", AllowCreateArcher);
        AllowedResolution = Reader->ReadInt32("Permission", "MaxResolution", AllowedResolution);

        //Optional
        SafeZoneBorder = Reader->ReadBoolean("Optional", "SafeZoneBorder", SafeZoneBorder);
        SafeZoneHealing = Reader->ReadBoolean("Optional", "SafeZoneHealing", SafeZoneHealing);
        GatherOrbsPerLevel = Reader->ReadBoolean("Optional", "GatherOrbsPerLevel", GatherOrbsPerLevel);
        ExpMobLevelDifference = Reader->ReadBoolean("Optional", "ExpMobLevelDifference", ExpMobLevelDifference);
        GameMasterEffect = Reader->ReadBoolean("Optional", "GameMasterEffect", GameMasterEffect);
        LineMessageTimer = Reader->ReadInt32("Optional", "LineMessageTimer", LineMessageTimer);

        //Database
        SaveDelay = Reader->ReadInt32("Database", "SaveDelay", SaveDelay);
        CredxGold = Reader->ReadInt16("Database", "CredxGold", CredxGold);

        //Game
        DropRate = Reader->ReadSingle("Game", "DropRate", DropRate);
        ExpRate = Reader->ReadSingle("Game", "ExpRate", ExpRate);
        ItemTimeOut = Reader->ReadInt32("Game", "ItemTimeOut", ItemTimeOut);
        PlayerDiedItemTimeOut = Reader->ReadInt32("Game", "PlayerDiedItemTimeOut", PlayerDiedItemTimeOut);
        PetSave = Reader->ReadBoolean("Game", "PetSave", PetSave);
        PKDelay = Reader->ReadInt32("Game", "PKDelay", PKDelay);
        SkeletonName = Reader->ReadString("Game", "SkeletonName", SkeletonName);
        BugBatName = Reader->ReadString("Game", "BugBatName", BugBatName);
        ShinsuName = Reader->ReadString("Game", "ShinsuName", ShinsuName);
        Zuma1 = Reader->ReadString("Game", "Zuma1", Zuma1);
        Zuma2 = Reader->ReadString("Game", "Zuma2", Zuma2);
        Zuma3 = Reader->ReadString("Game", "Zuma3", Zuma3);
        Zuma4 = Reader->ReadString("Game", "Zuma4", Zuma4);
        Zuma5 = Reader->ReadString("Game", "Zuma5", Zuma5);
        Zuma6 = Reader->ReadString("Game", "Zuma6", Zuma6);
        Zuma7 = Reader->ReadString("Game", "Zuma7", Zuma7);
        Turtle1 = Reader->ReadString("Game", "Turtle1", Turtle1);
        Turtle2 = Reader->ReadString("Game", "Turtle2", Turtle2);
        Turtle3 = Reader->ReadString("Game", "Turtle3", Turtle3);
        Turtle4 = Reader->ReadString("Game", "Turtle4", Turtle4);
        Turtle5 = Reader->ReadString("Game", "Turtle5", Turtle5);
        BoneMonster1 = Reader->ReadString("Game", "BoneMonster1", BoneMonster1);
        BoneMonster2 = Reader->ReadString("Game", "BoneMonster2", BoneMonster2);
        BoneMonster3 = Reader->ReadString("Game", "BoneMonster3", BoneMonster3);
        BoneMonster4 = Reader->ReadString("Game", "BoneMonster4", BoneMonster4);
        BehemothMonster1 = Reader->ReadString("Game", "BehemothMonster1", BehemothMonster1);
        BehemothMonster2 = Reader->ReadString("Game", "BehemothMonster2", BehemothMonster2);
        BehemothMonster3 = Reader->ReadString("Game", "BehemothMonster3", BehemothMonster3);
        HellKnight1 = Reader->ReadString("Game", "HellKnight1", HellKnight1);
        HellKnight2 = Reader->ReadString("Game", "HellKnight2", HellKnight2);
        HellKnight3 = Reader->ReadString("Game", "HellKnight3", HellKnight3);
        HellKnight4 = Reader->ReadString("Game", "HellKnight4", HellKnight4);
        HellBomb1 = Reader->ReadString("Game", "HellBomb1", HellBomb1);
        HellBomb2 = Reader->ReadString("Game", "HellBomb2", HellBomb2);
        HellBomb3 = Reader->ReadString("Game", "HellBomb3", HellBomb3);
        GeneralMeowMeowMob1 = Reader->ReadString("Game", "GeneralMeowMeowMob1", GeneralMeowMeowMob1);
        GeneralMeowMeowMob2 = Reader->ReadString("Game", "GeneralMeowMeowMob2", GeneralMeowMeowMob2);
        GeneralMeowMeowMob3 = Reader->ReadString("Game", "GeneralMeowMeowMob3", GeneralMeowMeowMob3);
        GeneralMeowMeowMob4 = Reader->ReadString("Game", "GeneralMeowMeowMob4", GeneralMeowMeowMob4);
        WhiteSnake = Reader->ReadString("Game", "WhiteSnake", WhiteSnake);
        AngelName = Reader->ReadString("Game", "AngelName", AngelName);
        BombSpiderName = Reader->ReadString("Game", "BombSpiderName", BombSpiderName);
        CloneName = Reader->ReadString("Game", "CloneName", CloneName);
        FishingMonster = Reader->ReadString("Game", "FishMonster", FishingMonster);
        AssassinCloneName = Reader->ReadString("Game", "AssassinCloneName", AssassinCloneName);
        VampireName = Reader->ReadString("Game", "VampireName", VampireName);
        ToadName = Reader->ReadString("Game", "ToadName", ToadName);
        SnakeTotemName = Reader->ReadString("Game", "SnakeTotemName", SnakeTotemName);
        SnakesName = Reader->ReadString("Game", "SnakesName", SnakesName);
        AncientBatName = Reader->ReadString("Game", "AncientBatName", AncientBatName);
        TucsonGeneralEgg = Reader->ReadString("Game", "TucsonGeneralEgg", TucsonGeneralEgg);
        setGroupInviteDelay(Reader->ReadInt64("Game", "GroupInviteDelay", getGroupInviteDelay()));
        setTradeDelay(Reader->ReadInt64("Game", "TradeDelay", getTradeDelay()));

        //Rested
        RestedPeriod = Reader->ReadInt32("Rested", "Period", RestedPeriod);
        RestedBuffLength = Reader->ReadInt32("Rested", "BuffLength", RestedBuffLength);
        RestedExpBonus = Reader->ReadInt32("Rested", "ExpBonus", RestedExpBonus);
        RestedMaxBonus = Reader->ReadInt32("Rested", "MaxBonus", RestedMaxBonus);

        //Items
        HealRing = Reader->ReadString("Items", "HealRing", HealRing);
        FireRing = Reader->ReadString("Items", "FireRing", FireRing);
        BlinkSkill = Reader->ReadString("Items", "BlinkSkill", BlinkSkill);

        //PKTown
        PKTownMapName = Reader->ReadString("PKTown", "PKTownMapName", PKTownMapName);
        PKTownPositionX = Reader->ReadInt32("PKTown", "PKTownPositionX", PKTownPositionX);
        PKTownPositionY = Reader->ReadInt32("PKTown", "PKTownPositionY", PKTownPositionY);

        DropGold = Reader->ReadBoolean("DropGold", "DropGold", DropGold);
        MaxDropGold = Reader->ReadUInt32("DropGold", "MaxDropGold", MaxDropGold);

        MagicResistWeight = Reader->ReadByte("Items","MagicResistWeight",MagicResistWeight);
        PoisonResistWeight = Reader->ReadByte("Items","PoisonResistWeight",PoisonResistWeight);
        CriticalRateWeight = Reader->ReadByte("Items","CriticalRateWeight",CriticalRateWeight);
        CriticalDamageWeight = std::max(static_cast<unsigned char>(1), Reader->ReadByte("Items","CriticalDamageWeight",CriticalDamageWeight));
        FreezingAttackWeight = Reader->ReadByte("Items","FreezingAttackWeight",FreezingAttackWeight);
        PoisonAttackWeight = Reader->ReadByte("Items","PoisonAttackWeight",PoisonAttackWeight);
        HealthRegenWeight = std::max(static_cast<unsigned char>(1), Reader->ReadByte("Items", "HealthRegenWeight", HealthRegenWeight));
        ManaRegenWeight = std::max(static_cast<unsigned char>(1), Reader->ReadByte("Items", "ManaRegenWeight", ManaRegenWeight));
        MaxLuck = Reader->ReadByte("Items", "MaxLuck", MaxLuck);

        PvpCanResistMagic = Reader->ReadBoolean("Items","PvpCanResistMagic",PvpCanResistMagic);
        PvpCanResistPoison = Reader->ReadBoolean("Items", "PvpCanResistPoison", PvpCanResistPoison);
        PvpCanFreeze = Reader->ReadBoolean("Items", "PvpCanFreeze", PvpCanFreeze);

        RangeAccuracyBonus = Reader->ReadByte("Bonus", "RangeAccuracyBonus", RangeAccuracyBonus);

        //IntelligentCreature
        CreatureBlackStoneName = Reader->ReadString("IntelligentCreatures", "CreatureBlackStoneName", CreatureBlackStoneName);

        if (!FileSystem::directoryExists(EnvirPath))
        {
            FileSystem::createDirectory(EnvirPath);
        }
        if (!FileSystem::directoryExists(ConfigPath))
        {
            FileSystem::createDirectory(ConfigPath);
        }

        if (!FileSystem::directoryExists(MapPath))
        {
            FileSystem::createDirectory(MapPath);
        }
        if (!FileSystem::directoryExists(NPCPath))
        {
            FileSystem::createDirectory(NPCPath);
        }
        if (!FileSystem::directoryExists(GoodsPath))
        {
            FileSystem::createDirectory(GoodsPath);
        }
        if (!FileSystem::directoryExists(QuestPath))
        {
            FileSystem::createDirectory(QuestPath);
        }
        if (!FileSystem::directoryExists(DropPath))
        {
            FileSystem::createDirectory(DropPath);
        }
        if (!FileSystem::directoryExists(ExportPath))
        {
            FileSystem::createDirectory(ExportPath);
        }
        if (!FileSystem::directoryExists(RoutePath))
        {
            FileSystem::createDirectory(RoutePath);
        }
        if (!FileSystem::directoryExists(NameListPath))
        {
            FileSystem::createDirectory(NameListPath);
        }
        if (!FileSystem::directoryExists(RecipePath))
        {
            FileSystem::createDirectory(RecipePath);
        }

        std::string fileName = FileSystem::combine(Settings::NPCPath, DefaultNPCFilename + ".txt");

        if (!FileSystem::fileExists(fileName))
        {
            FileStream *NewFile = File::Create(fileName);
            NewFile->Close();
        }

        fileName = FileSystem::combine(Settings::NPCPath, MonsterNPCFilename + ".txt");

        if (!FileSystem::fileExists(fileName))
        {
            FileStream *NewFile = File::Create(fileName);
            NewFile->Close();
        }

        fileName = FileSystem::combine(Settings::NPCPath, RobotNPCFilename + ".txt");

        if (!FileSystem::fileExists(fileName))
        {
            FileStream *NewFile = File::Create(fileName);
            NewFile->Close();
        }

        LoadVersion();
        LoadEXP();
        LoadBaseStats();
        LoadRandomItemStats();
        LoadMines();
        LoadGuildSettings();
        LoadAwakeAttribute();
        LoadFishing();
        LoadMail();
        LoadRefine();
        LoadMarriage();
        LoadMentor();
        LoadGoods();
        LoadGem();
        LoadNotice();

        GameLanguage::LoadServerLanguage(FileSystem::combine(ConfigPath, "Language.ini"));
    }

    void Settings::LoadNotice()
    {
        Notice = new Notice();

        if (!FileSystem::fileExists(NoticePath))
        {
            FileStream *NewFile = File::Create(NoticePath);
            NewFile->Close();
        }

        auto lines = File::ReadAllLines(NoticePath);

        if (lines.empty())
        {
            return;
        }

        Notice->LastUpdate = File::GetLastWriteTime(NoticePath);

        auto links = std::vector<std::string>();

        for (int i = 0; i < lines.size(); i++)
        {
            auto line = lines[i];

//C# TO C++ CONVERTER TODO TASK: The following System.String compare method is not converted:
            if (std::string::Compare(line, "TITLE", false) > 0 && line.find("=") != std::string::npos)
            {
                Notice->Title = StringHelper::split(line, '=')[1];
                continue;
            }

            Notice->Message += line + "\r\n";
        }
    }

    void Settings::Save()
    {
        //General
        Reader->Write("General", "VersionPath", VersionPath);
        Reader->Write("General", "CheckVersion", CheckVersion);
        Reader->Write("General", "RelogDelay", RelogDelay);
        Reader->Write("General", "Multithreaded", Multithreaded);
        Reader->Write("General", "ThreadLimit", ThreadLimit);
        Reader->Write("General", "TestServer", TestServer);
        Reader->Write("General", "EnforceDBChecks", EnforceDBChecks);
        Reader->Write("General", "MonsterProcessWhenAlone", MonsterProcessWhenAlone);
        Reader->Write("General", "MonsterProcessWhenStacked", MonsterProcessWhenStacked);

        //Paths
        Reader->Write("Network", "IPAddress", IPAddress);
        Reader->Write("Network", "Port", Port);
        Reader->Write("Network", "TimeOut", TimeOut);
        Reader->Write("Network", "MaxUser", MaxUser);
        Reader->Write("Network", "MaxIP", MaxIP);

        //HTTP
        Reader->Write("Network", "StartHTTPService", StartHTTPService);
        Reader->Write("Network", "HTTPIPAddress", HTTPIPAddress);
        Reader->Write("Network", "HTTPTrustedIPAddress", HTTPTrustedIPAddress);

        //Permission
        Reader->Write("Permission", "AllowNewAccount", AllowNewAccount);
        Reader->Write("Permission", "AllowChangePassword", AllowChangePassword);
        Reader->Write("Permission", "AllowLogin", AllowLogin);
        Reader->Write("Permission", "AllowNewCharacter", AllowNewCharacter);
        Reader->Write("Permission", "AllowDeleteCharacter", AllowDeleteCharacter);
        Reader->Write("Permission", "AllowStartGame", AllowStartGame);
        Reader->Write("Permission", "AllowCreateAssassin", AllowCreateAssassin);
        Reader->Write("Permission", "AllowCreateArcher", AllowCreateArcher);
        Reader->Write("Permission", "MaxResolution", AllowedResolution);

        //Optional
        Reader->Write("Optional", "SafeZoneBorder", SafeZoneBorder);
        Reader->Write("Optional", "SafeZoneHealing", SafeZoneHealing);
        Reader->Write("Optional", "GatherOrbsPerLevel", GatherOrbsPerLevel);
        Reader->Write("Optional", "ExpMobLevelDifference", ExpMobLevelDifference);
        Reader->Write("Optional", "GameMasterEffect", GameMasterEffect);
        Reader->Write("Optional", "LineMessageTimer", LineMessageTimer);

        //Database
        Reader->Write("Database", "SaveDelay", SaveDelay);
        Reader->Write("Database", "CredxGold", CredxGold);

        //Game
        Reader->Write("Game", "DropRate", DropRate);
        Reader->Write("Game", "ExpRate", ExpRate);
        Reader->Write("Game", "ItemTimeOut", ItemTimeOut);
        Reader->Write("Game", "PlayerDiedItemTimeOut", PlayerDiedItemTimeOut);
        Reader->Write("Game", "PetSave", PetSave);
        Reader->Write("Game", "PKDelay", PKDelay);
        Reader->Write("Game", "SkeletonName", SkeletonName);
        Reader->Write("Game", "BugBatName", BugBatName);
        Reader->Write("Game", "ShinsuName", ShinsuName);

        Reader->Write("Game", "Zuma1", Zuma1);
        Reader->Write("Game", "Zuma2", Zuma2);
        Reader->Write("Game", "Zuma3", Zuma3);
        Reader->Write("Game", "Zuma4", Zuma4);
        Reader->Write("Game", "Zuma5", Zuma5);
        Reader->Write("Game", "Zuma6", Zuma6);
        Reader->Write("Game", "Zuma7", Zuma7);

        Reader->Write("Game", "Turtle1", Turtle1);
        Reader->Write("Game", "Turtle2", Turtle2);
        Reader->Write("Game", "Turtle3", Turtle3);
        Reader->Write("Game", "Turtle4", Turtle4);
        Reader->Write("Game", "Turtle5", Turtle5);

        Reader->Write("Game", "BoneMonster1", BoneMonster1);
        Reader->Write("Game", "BoneMonster2", BoneMonster2);
        Reader->Write("Game", "BoneMonster3", BoneMonster3);
        Reader->Write("Game", "BoneMonster4", BoneMonster4);

        Reader->Write("Game", "BehemothMonster1", BehemothMonster1);
        Reader->Write("Game", "BehemothMonster2", BehemothMonster2);
        Reader->Write("Game", "BehemothMonster3", BehemothMonster3);

        Reader->Write("Game", "HellKnight1", HellKnight1);
        Reader->Write("Game", "HellKnight2", HellKnight2);
        Reader->Write("Game", "HellKnight3", HellKnight3);
        Reader->Write("Game", "HellKnight4", HellKnight4);
        Reader->Write("Game", "HellBomb1", HellBomb1);
        Reader->Write("Game", "HellBomb2", HellBomb2);
        Reader->Write("Game", "HellBomb3", HellBomb3);

        Reader->Write("Game", "WhiteSnake", WhiteSnake);
        Reader->Write("Game", "AngelName", AngelName);
        Reader->Write("Game", "BombSpiderName", BombSpiderName);
        Reader->Write("Game", "CloneName", CloneName);
        Reader->Write("Game", "AssassinCloneName", AssassinCloneName);

        Reader->Write("Game", "VampireName", VampireName);
        Reader->Write("Game", "ToadName", ToadName);
        Reader->Write("Game", "SnakeTotemName", SnakeTotemName);
        Reader->Write("Game", "SnakesName", SnakesName);
        Reader->Write("Game", "AncientBatName", AncientBatName);
        Reader->Write("Game", "TucsonGeneralEgg", TucsonGeneralEgg);
        Reader->Write("Game", "GroupInviteDelay", getGroupInviteDelay());
        Reader->Write("Game", "TradeDelay", getTradeDelay());

        Reader->Write("Rested", "Period", RestedPeriod);
        Reader->Write("Rested", "BuffLength", RestedBuffLength);
        Reader->Write("Rested", "ExpBonus", RestedExpBonus);
        Reader->Write("Rested", "MaxBonus", RestedMaxBonus);

        Reader->Write("Items", "HealRing", HealRing);
        Reader->Write("Items", "FireRing", FireRing);
        Reader->Write("Items", "BlinkSkill", BlinkSkill);

        Reader->Write("PKTown", "PKTownMapName", PKTownMapName);
        Reader->Write("PKTown", "PKTownPositionX", PKTownPositionX);
        Reader->Write("PKTown", "PKTownPositionY", PKTownPositionY);

        Reader->Write("DropGold", "DropGold", DropGold);
        Reader->Write("DropGold", "MaxDropGold", MaxDropGold);

        Reader->Write("Items", "MagicResistWeight", MagicResistWeight);
        Reader->Write("Items", "PoisonResistWeight", PoisonResistWeight);
        Reader->Write("Items", "CriticalRateWeight", CriticalRateWeight);
        Reader->Write("Items", "CriticalDamageWeight", CriticalDamageWeight);
        Reader->Write("Items", "FreezingAttackWeight", FreezingAttackWeight);
        Reader->Write("Items", "PoisonAttackWeight", PoisonAttackWeight);
        Reader->Write("Items", "HealthRegenWeight", HealthRegenWeight);
        Reader->Write("Items", "ManaRegenWeight", ManaRegenWeight);
        Reader->Write("Items", "MaxLuck", MaxLuck);

        Reader->Write("Items", "PvpCanResistMagic", PvpCanResistMagic);
        Reader->Write("Items", "PvpCanResistPoison", PvpCanResistPoison);
        Reader->Write("Items", "PvpCanFreeze", PvpCanFreeze);

        Reader->Write("Bonus", "RangeAccuracyBonus", RangeAccuracyBonus);

        Reader->Write("Game", "GeneralMeowMeowMob1", GeneralMeowMeowMob1);
        Reader->Write("Game", "GeneralMeowMeowMob2", GeneralMeowMeowMob2);
        Reader->Write("Game", "GeneralMeowMeowMob3", GeneralMeowMeowMob3);
        Reader->Write("Game", "GeneralMeowMeowMob4", GeneralMeowMeowMob4);

        //IntelligentCreature
        Reader->Write("IntelligentCreatures", "CreatureBlackStoneName", CreatureBlackStoneName);

        SaveAwakeAttribute();
    }

    void Settings::LoadEXP()
    {
        long long exp = 100;
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "ExpList.ini"));

        for (int i = 1; i <= 500; i++)
        {
            exp = reader->ReadInt64("Exp", "Level" + std::to_string(i), exp);
            ExperienceList.push_back(exp);
        }

        //ArcherSpells - Elemental system
        reader = new InIReader(FileSystem::combine(ConfigPath, "OrbsExpList.ini"));
        for (int i = 1; i <= 4; i++)
        {
            exp = i * 50; //default exp value
            exp = reader->ReadInt64("Exp", "Orb" + std::to_string(i), exp);
            OrbsExpList.push_back(exp);
            exp = i * 2; //default defense value
            exp = reader->ReadInt64("Def", "Orb" + std::to_string(i), exp);
            OrbsDefList.push_back(exp);
            exp = i * 4; //default power value
            exp = reader->ReadInt64("Att", "Orb" + std::to_string(i), exp);
            OrbsDmgList.push_back(exp);
        }

        delete reader;
    }

    void Settings::LoadBaseStats()
    {
        for (int i = 0; i < ClassBaseStats.size(); i++)
        {
            if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, StringHelper::formatSimple("BaseStats{0}.ini", ClassBaseStats[i]->Job))))
            {
                SaveBaseStats({new BaseStats(ClassBaseStats[i]->Job)});
                continue;
            }

            InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, StringHelper::formatSimple("BaseStats{0}.ini", ClassBaseStats[i]->Job)));

            ClassBaseStats[i]->Stats->clear();
            ClassBaseStats[i]->Caps->Clear();

//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to the C# 'typeof' operator:
            for (auto stat : Enum::GetValues(typeof(Stat)))
            {
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                auto key = stat->ToString();

                auto formula = reader->ReadString(key, "Formula", "", false);

                if (!formula.empty())
                {
                    auto baseStat = new BaseStat(static_cast<Stat>(stat));
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to the C# 'typeof' operator:
                    baseStat->FormulaType = std::any_cast<StatFormula>(Enum::Parse(typeof(StatFormula), formula, true));
                    baseStat->Base = reader->ReadInt32(key, "Base", 0);
                    baseStat->Gain = reader->ReadFloat(key, "Gain", 0);
                    baseStat->GainRate = reader->ReadFloat(key, "GainRate", 0);
                    baseStat->Max = reader->ReadInt32(key, "Max", 0);

                    ClassBaseStats[i]->Stats.push_back(baseStat);

//C# TO C++ CONVERTER TODO TASK: A 'delete baseStat' statement was not added since baseStat was passed to a method or constructor. Handle memory management manually.
                }

                ClassBaseStats[i]->Caps[static_cast<Stat>(stat)] = reader->ReadInt32("Caps", key, 0, false);
            }

            delete reader;
        }
    }

    void Settings::SaveBaseStats(std::vector<BaseStats*> &classStats)
    {
        if (classStats.empty())
        {
            classStats = ClassBaseStats;
        }

        for (auto baseStats : classStats)
        {
            File::Delete(FileSystem::combine(ConfigPath, StringHelper::formatSimple("BaseStats{0}.ini", baseStats->Job)));
            InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, StringHelper::formatSimple("BaseStats{0}.ini", baseStats->Job)));

            for (auto stat : *baseStats->Stats)
            {
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                reader->Write(stat->Type.ToString(), "Formula", stat->FormulaType.ToString());
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                reader->Write(stat->Type.ToString(), "Base", std::to_string(stat->Base));
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                reader->Write(stat->Type.ToString(), "Gain", std::to_string(stat->Gain));
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                reader->Write(stat->Type.ToString(), "GainRate", std::to_string(stat->GainRate));
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                reader->Write(stat->Type.ToString(), "Max", std::to_string(stat->Max));
            }

            for (auto item : *baseStats->Caps)
            {
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                reader->Write("Caps", item->second.Key->ToString(), item->second->Value);
            }

            delete reader;
        }
    }

    void Settings::LoadRandomItemStats()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "RandomItemStats.ini")))
        {
            RandomItemStat tempVar();
            RandomItemStatsList.push_back(&tempVar);
            RandomItemStat tempVar2(ItemType::Weapon);
            RandomItemStatsList.push_back(&tempVar2);
            RandomItemStat tempVar3(ItemType::Armour);
            RandomItemStatsList.push_back(&tempVar3);
            RandomItemStat tempVar4(ItemType::Helmet);
            RandomItemStatsList.push_back(&tempVar4);
            RandomItemStat tempVar5(ItemType::Necklace);
            RandomItemStatsList.push_back(&tempVar5);
            RandomItemStat tempVar6(ItemType::Bracelet);
            RandomItemStatsList.push_back(&tempVar6);
            RandomItemStat tempVar7(ItemType::Ring);
            RandomItemStatsList.push_back(&tempVar7);
            RandomItemStat tempVar8(ItemType::Belt);
            RandomItemStatsList.push_back(&tempVar8);
            SaveRandomItemStats();
            return;
        }

        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "RandomItemStats.ini"));
        int i = 0;
        RandomItemStat *stat;
        while (reader->ReadByte("Item" + std::to_string(i),"MaxDuraChance",255) != 255)
        {
            stat = new RandomItemStat();
            stat->MaxDuraChance = reader->ReadByte("Item" + std::to_string(i), "MaxDuraChance", 0);
            stat->MaxDuraStatChance = reader->ReadByte("Item" + std::to_string(i), "MaxDuraStatChance", 1);
            stat->MaxDuraMaxStat = reader->ReadByte("Item" + std::to_string(i), "MaxDuraMaxStat", 1);
            stat->MaxAcChance = reader->ReadByte("Item" + std::to_string(i), "MaxAcChance", 0);
            stat->MaxAcStatChance = reader->ReadByte("Item" + std::to_string(i), "MaxAcStatChance", 1);
            stat->MaxAcMaxStat = reader->ReadByte("Item" + std::to_string(i), "MaxAcMaxStat", 1);
            stat->MaxMacChance = reader->ReadByte("Item" + std::to_string(i), "MaxMacChance", 0);
            stat->MaxMacStatChance = reader->ReadByte("Item" + std::to_string(i), "MaxMacStatChance", 1);
            stat->MaxMacMaxStat = reader->ReadByte("Item" + std::to_string(i), "MaxMACMaxStat", 1);
            stat->MaxDcChance = reader->ReadByte("Item" + std::to_string(i), "MaxDcChance", 0);
            stat->MaxDcStatChance = reader->ReadByte("Item" + std::to_string(i), "MaxDcStatChance", 1);
            stat->MaxDcMaxStat = reader->ReadByte("Item" + std::to_string(i), "MaxDcMaxStat", 1);
            stat->MaxMcChance = reader->ReadByte("Item" + std::to_string(i), "MaxMcChance", 0);
            stat->MaxMcStatChance = reader->ReadByte("Item" + std::to_string(i), "MaxMcStatChance", 1);
            stat->MaxMcMaxStat = reader->ReadByte("Item" + std::to_string(i), "MaxMcMaxStat", 1);
            stat->MaxScChance = reader->ReadByte("Item" + std::to_string(i), "MaxScChance", 0);
            stat->MaxScStatChance = reader->ReadByte("Item" + std::to_string(i), "MaxScStatChance", 1);
            stat->MaxScMaxStat = reader->ReadByte("Item" + std::to_string(i), "MaxScMaxStat", 1);
            stat->AccuracyChance = reader->ReadByte("Item" + std::to_string(i), "AccuracyChance", 0);
            stat->AccuracyStatChance = reader->ReadByte("Item" + std::to_string(i), "AccuracyStatChance", 1);
            stat->AccuracyMaxStat = reader->ReadByte("Item" + std::to_string(i), "AccuracyMaxStat", 1);
            stat->AgilityChance = reader->ReadByte("Item" + std::to_string(i), "AgilityChance", 0);
            stat->AgilityStatChance = reader->ReadByte("Item" + std::to_string(i), "AgilityStatChance", 1);
            stat->AgilityMaxStat = reader->ReadByte("Item" + std::to_string(i), "AgilityMaxStat", 1);
            stat->HpChance = reader->ReadByte("Item" + std::to_string(i), "HpChance", 0);
            stat->HpStatChance = reader->ReadByte("Item" + std::to_string(i), "HpStatChance", 1);
            stat->HpMaxStat = reader->ReadByte("Item" + std::to_string(i), "HpMaxStat", 1);
            stat->MpChance = reader->ReadByte("Item" + std::to_string(i), "MpChance", 0);
            stat->MpStatChance = reader->ReadByte("Item" + std::to_string(i), "MpStatChance", 1);
            stat->MpMaxStat = reader->ReadByte("Item" + std::to_string(i), "MpMaxStat", 1);
            stat->StrongChance = reader->ReadByte("Item" + std::to_string(i), "StrongChance", 0);
            stat->StrongStatChance = reader->ReadByte("Item" + std::to_string(i), "StrongStatChance", 1);
            stat->StrongMaxStat = reader->ReadByte("Item" + std::to_string(i), "StrongMaxStat", 1);
            stat->MagicResistChance = reader->ReadByte("Item" + std::to_string(i), "MagicResistChance", 0);
            stat->MagicResistStatChance = reader->ReadByte("Item" + std::to_string(i), "MagicResistStatChance", 1);
            stat->MagicResistMaxStat = reader->ReadByte("Item" + std::to_string(i), "MagicResistMaxStat", 1);
            stat->PoisonResistChance = reader->ReadByte("Item" + std::to_string(i), "PoisonResistChance", 0);
            stat->PoisonResistStatChance = reader->ReadByte("Item" + std::to_string(i), "PoisonResistStatChance", 1);
            stat->PoisonResistMaxStat = reader->ReadByte("Item" + std::to_string(i), "PoisonResistMaxStat", 1);
            stat->HpRecovChance = reader->ReadByte("Item" + std::to_string(i), "HpRecovChance", 0);
            stat->HpRecovStatChance = reader->ReadByte("Item" + std::to_string(i), "HpRecovStatChance", 1);
            stat->HpRecovMaxStat = reader->ReadByte("Item" + std::to_string(i), "HpRecovMaxStat", 1);
            stat->MpRecovChance = reader->ReadByte("Item" + std::to_string(i), "MpRecovChance", 0);
            stat->MpRecovStatChance = reader->ReadByte("Item" + std::to_string(i), "MpRecovStatChance", 1);
            stat->MpRecovMaxStat = reader->ReadByte("Item" + std::to_string(i), "MpRecovMaxStat", 1);
            stat->PoisonRecovChance = reader->ReadByte("Item" + std::to_string(i), "PoisonRecovChance", 0);
            stat->PoisonRecovStatChance = reader->ReadByte("Item" + std::to_string(i), "PoisonRecovStatChance", 1);
            stat->PoisonRecovMaxStat = reader->ReadByte("Item" + std::to_string(i), "PoisonRecovMaxStat", 1);
            stat->CriticalRateChance = reader->ReadByte("Item" + std::to_string(i), "CriticalRateChance", 0);
            stat->CriticalRateStatChance = reader->ReadByte("Item" + std::to_string(i), "CriticalRateStatChance", 1);
            stat->CriticalRateMaxStat = reader->ReadByte("Item" + std::to_string(i), "CriticalRateMaxStat", 1);
            stat->CriticalDamageChance = reader->ReadByte("Item" + std::to_string(i), "CriticalDamageChance", 0);
            stat->CriticalDamageStatChance = reader->ReadByte("Item" + std::to_string(i), "CriticalDamageStatChance", 1);
            stat->CriticalDamageMaxStat = reader->ReadByte("Item" + std::to_string(i), "CriticalDamageMaxStat", 1);
            stat->FreezeChance = reader->ReadByte("Item" + std::to_string(i), "FreezeChance", 0);
            stat->FreezeStatChance = reader->ReadByte("Item" + std::to_string(i), "FreezeStatChance", 1);
            stat->FreezeMaxStat = reader->ReadByte("Item" + std::to_string(i), "FreezeMaxStat", 1);
            stat->PoisonAttackChance = reader->ReadByte("Item" + std::to_string(i), "PoisonAttackChance", 0);
            stat->PoisonAttackStatChance = reader->ReadByte("Item" + std::to_string(i), "PoisonAttackStatChance", 1);
            stat->PoisonAttackMaxStat = reader->ReadByte("Item" + std::to_string(i), "PoisonAttackMaxStat", 1);
            stat->AttackSpeedChance = reader->ReadByte("Item" + std::to_string(i), "AttackSpeedChance", 0);
            stat->AttackSpeedStatChance = reader->ReadByte("Item" + std::to_string(i), "AttackSpeedStatChance", 1);
            stat->AttackSpeedMaxStat = reader->ReadByte("Item" + std::to_string(i), "AttackSpeedMaxStat", 1);
            stat->LuckChance = reader->ReadByte("Item" + std::to_string(i), "LuckChance", 0);
            stat->LuckStatChance = reader->ReadByte("Item" + std::to_string(i), "LuckStatChance", 1);
            stat->LuckMaxStat = reader->ReadByte("Item" + std::to_string(i), "LuckMaxStat", 1);
            stat->CurseChance = reader->ReadByte("Item" + std::to_string(i), "CurseChance", 0);
            stat->SlotChance = reader->ReadByte("Item" + std::to_string(i), "SlotChance", 0);
            stat->SlotStatChance = reader->ReadByte("Item" + std::to_string(i), "SlotStatChance", 0);
            stat->SlotMaxStat = reader->ReadByte("Item" + std::to_string(i), "SlotMaxStat", 0);
            RandomItemStatsList.push_back(stat);
            i++;
        }

//C# TO C++ CONVERTER TODO TASK: A 'delete stat' statement was not added since stat was passed to a method or constructor. Handle memory management manually.
        delete reader;
    }

    void Settings::SaveRandomItemStats()
    {
        File::Delete(FileSystem::combine(ConfigPath, "RandomItemStats.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "RandomItemStats.ini"));
        RandomItemStat *stat;
        for (int i = 0; i < RandomItemStatsList.size(); i++)
        {
            stat = RandomItemStatsList[i];
            reader->Write("Item" + std::to_string(i), "MaxDuraChance", stat->MaxDuraChance);
            reader->Write("Item" + std::to_string(i), "MaxDuraStatChance", stat->MaxDuraStatChance);
            reader->Write("Item" + std::to_string(i), "MaxDuraMaxStat", stat->MaxDuraMaxStat);
            reader->Write("Item" + std::to_string(i), "MaxAcChance", stat->MaxAcChance);
            reader->Write("Item" + std::to_string(i), "MaxAcStatChance", stat->MaxAcStatChance);
            reader->Write("Item" + std::to_string(i), "MaxAcMaxStat", stat->MaxAcMaxStat);
            reader->Write("Item" + std::to_string(i), "MaxMacChance", stat->MaxMacChance);
            reader->Write("Item" + std::to_string(i), "MaxMacStatChance", stat->MaxMacStatChance);
            reader->Write("Item" + std::to_string(i), "MaxMACMaxStat", stat->MaxMacMaxStat);
            reader->Write("Item" + std::to_string(i), "MaxDcChance", stat->MaxDcChance);
            reader->Write("Item" + std::to_string(i), "MaxDcStatChance", stat->MaxDcStatChance);
            reader->Write("Item" + std::to_string(i), "MaxDcMaxStat", stat->MaxDcMaxStat);
            reader->Write("Item" + std::to_string(i), "MaxMcChance", stat->MaxMcChance);
            reader->Write("Item" + std::to_string(i), "MaxMcStatChance", stat->MaxMcStatChance);
            reader->Write("Item" + std::to_string(i), "MaxMcMaxStat", stat->MaxMcMaxStat);
            reader->Write("Item" + std::to_string(i), "MaxScChance", stat->MaxScChance);
            reader->Write("Item" + std::to_string(i), "MaxScStatChance", stat->MaxScStatChance);
            reader->Write("Item" + std::to_string(i), "MaxScMaxStat", stat->MaxScMaxStat);
            reader->Write("Item" + std::to_string(i), "AccuracyChance", stat->AccuracyChance);
            reader->Write("Item" + std::to_string(i), "AccuracyStatChance", stat->AccuracyStatChance);
            reader->Write("Item" + std::to_string(i), "AccuracyMaxStat", stat->AccuracyMaxStat);
            reader->Write("Item" + std::to_string(i), "AgilityChance", stat->AgilityChance);
            reader->Write("Item" + std::to_string(i), "AgilityStatChance", stat->AgilityStatChance);
            reader->Write("Item" + std::to_string(i), "AgilityMaxStat", stat->AgilityMaxStat);
            reader->Write("Item" + std::to_string(i), "HpChance", stat->HpChance);
            reader->Write("Item" + std::to_string(i), "HpStatChance", stat->HpStatChance);
            reader->Write("Item" + std::to_string(i), "HpMaxStat", stat->HpMaxStat);
            reader->Write("Item" + std::to_string(i), "MpChance", stat->MpChance);
            reader->Write("Item" + std::to_string(i), "MpStatChance", stat->MpStatChance);
            reader->Write("Item" + std::to_string(i), "MpMaxStat", stat->MpMaxStat);
            reader->Write("Item" + std::to_string(i), "StrongChance", stat->StrongChance);
            reader->Write("Item" + std::to_string(i), "StrongStatChance", stat->StrongStatChance);
            reader->Write("Item" + std::to_string(i), "StrongMaxStat", stat->StrongMaxStat);
            reader->Write("Item" + std::to_string(i), "MagicResistChance", stat->MagicResistChance);
            reader->Write("Item" + std::to_string(i), "MagicResistStatChance", stat->MagicResistStatChance);
            reader->Write("Item" + std::to_string(i), "MagicResistMaxStat", stat->MagicResistMaxStat);
            reader->Write("Item" + std::to_string(i), "PoisonResistChance", stat->PoisonResistChance);
            reader->Write("Item" + std::to_string(i), "PoisonResistStatChance", stat->PoisonResistStatChance);
            reader->Write("Item" + std::to_string(i), "PoisonResistMaxStat", stat->PoisonResistMaxStat);
            reader->Write("Item" + std::to_string(i), "HpRecovChance", stat->HpRecovChance);
            reader->Write("Item" + std::to_string(i), "HpRecovStatChance", stat->HpRecovStatChance);
            reader->Write("Item" + std::to_string(i), "HpRecovMaxStat", stat->HpRecovMaxStat);
            reader->Write("Item" + std::to_string(i), "MpRecovChance", stat->MpRecovChance);
            reader->Write("Item" + std::to_string(i), "MpRecovStatChance", stat->MpRecovStatChance);
            reader->Write("Item" + std::to_string(i), "MpRecovMaxStat", stat->MpRecovMaxStat);
            reader->Write("Item" + std::to_string(i), "PoisonRecovChance", stat->PoisonRecovChance);
            reader->Write("Item" + std::to_string(i), "PoisonRecovStatChance", stat->PoisonRecovStatChance);
            reader->Write("Item" + std::to_string(i), "PoisonRecovMaxStat", stat->PoisonRecovMaxStat);
            reader->Write("Item" + std::to_string(i), "CriticalRateChance", stat->CriticalRateChance);
            reader->Write("Item" + std::to_string(i), "CriticalRateStatChance", stat->CriticalRateStatChance);
            reader->Write("Item" + std::to_string(i), "CriticalRateMaxStat", stat->CriticalRateMaxStat);
            reader->Write("Item" + std::to_string(i), "CriticalDamageChance", stat->CriticalDamageChance);
            reader->Write("Item" + std::to_string(i), "CriticalDamageStatChance", stat->CriticalDamageStatChance);
            reader->Write("Item" + std::to_string(i), "CriticalDamageMaxStat", stat->CriticalDamageMaxStat);
            reader->Write("Item" + std::to_string(i), "FreezeChance", stat->FreezeChance);
            reader->Write("Item" + std::to_string(i), "FreezeStatChance", stat->FreezeStatChance);
            reader->Write("Item" + std::to_string(i), "FreezeMaxStat", stat->FreezeMaxStat);
            reader->Write("Item" + std::to_string(i), "PoisonAttackChance", stat->PoisonAttackChance);
            reader->Write("Item" + std::to_string(i), "PoisonAttackStatChance", stat->PoisonAttackStatChance);
            reader->Write("Item" + std::to_string(i), "PoisonAttackMaxStat", stat->PoisonAttackMaxStat);
            reader->Write("Item" + std::to_string(i), "AttackSpeedChance", stat->AttackSpeedChance);
            reader->Write("Item" + std::to_string(i), "AttackSpeedStatChance", stat->AttackSpeedStatChance);
            reader->Write("Item" + std::to_string(i), "AttackSpeedMaxStat", stat->AttackSpeedMaxStat);
            reader->Write("Item" + std::to_string(i), "LuckChance", stat->LuckChance);
            reader->Write("Item" + std::to_string(i), "LuckStatChance", stat->LuckStatChance);
            reader->Write("Item" + std::to_string(i), "LuckMaxStat", stat->LuckMaxStat);
            reader->Write("Item" + std::to_string(i), "CurseChance", stat->CurseChance);
            reader->Write("Item" + std::to_string(i), "SlotChance", stat->SlotChance);
            reader->Write("Item" + std::to_string(i), "SlotStatChance", stat->SlotStatChance);
            reader->Write("Item" + std::to_string(i), "SlotMaxStat", stat->SlotMaxStat);
        }

        delete reader;
    }

    void Settings::LoadMines()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "Mines.ini")))
        {
            MineSet tempVar(1);
            MineSetList.push_back(&tempVar);
            MineSet tempVar2(2);
            MineSetList.push_back(&tempVar2);
            SaveMines();
            return;
        }
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "Mines.ini"));
        int i = 0;
        MineSet *mine;
        while (reader->ReadByte("Mine" + std::to_string(i), "SpotRegenRate", 255) != 255)
        {
            mine = new MineSet();
            mine->Name = reader->ReadString("Mine" + std::to_string(i), "Name", mine->Name);
            mine->SpotRegenRate = reader->ReadByte("Mine" + std::to_string(i), "SpotRegenRate", mine->SpotRegenRate);
            mine->MaxStones = reader->ReadByte("Mine" + std::to_string(i), "MaxStones", mine->MaxStones);
            mine->HitRate = reader->ReadByte("Mine" + std::to_string(i), "HitRate", mine->HitRate);
            mine->DropRate = reader->ReadByte("Mine" + std::to_string(i), "DropRate", mine->DropRate);
            mine->TotalSlots = reader->ReadByte("Mine" + std::to_string(i), "TotalSlots", mine->TotalSlots);
            int j = 0;
            while (reader->ReadByte("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MinSlot", 255) != 255)
            {
                MineDrop *tempVar3 = new MineDrop();
                tempVar3->ItemName = reader->ReadString("Mine" + std::to_string(i), "D" + std::to_string(j) + "-ItemName", "");
                tempVar3->MinSlot = reader->ReadByte("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MinSlot", 255);
                tempVar3->MaxSlot = reader->ReadByte("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MaxSlot", 255);
                tempVar3->MinDura = reader->ReadByte("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MinDura", 255);
                tempVar3->MaxDura = reader->ReadByte("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MaxDura", 255);
                tempVar3->BonusChance = reader->ReadByte("Mine" + std::to_string(i), "D" + std::to_string(j) + "-BonusChance", 255);
                tempVar3->MaxBonusDura = reader->ReadByte("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MaxBonusDura", 255);
                mine->Drops.push_back(tempVar3);
                j++;

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar3' statement was not added since tempVar3 was passed to a method or constructor. Handle memory management manually.
            }
            MineSetList.push_back(mine);
            i++;
        }

//C# TO C++ CONVERTER TODO TASK: A 'delete mine' statement was not added since mine was passed to a method or constructor. Handle memory management manually.
        delete reader;
    }

    void Settings::SaveMines()
    {
        File::Delete(FileSystem::combine(ConfigPath, "Mines.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "Mines.ini"));
        MineSet *mine;
        for (int i = 0; i < MineSetList.size(); i++)
        {
            mine = MineSetList[i];
            reader->Write("Mine" + std::to_string(i), "Name", mine->Name);
            reader->Write("Mine" + std::to_string(i), "SpotRegenRate", mine->SpotRegenRate);
            reader->Write("Mine" + std::to_string(i), "MaxStones", mine->MaxStones);
            reader->Write("Mine" + std::to_string(i), "HitRate", mine->HitRate);
            reader->Write("Mine" + std::to_string(i), "DropRate", mine->DropRate);
            reader->Write("Mine" + std::to_string(i), "TotalSlots", mine->TotalSlots);

            for (int j = 0; j < mine->Drops.size(); j++)
            {
                MineDrop *Drop = mine->Drops[j];
                reader->Write("Mine" + std::to_string(i), "D" + std::to_string(j) + "-ItemName", Drop->ItemName);
                reader->Write("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MinSlot", Drop->MinSlot);
                reader->Write("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MaxSlot", Drop->MaxSlot);
                reader->Write("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MinDura", Drop->MinDura);
                reader->Write("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MaxDura", Drop->MaxDura);
                reader->Write("Mine" + std::to_string(i), "D" + std::to_string(j) + "-BonusChance", Drop->BonusChance);
                reader->Write("Mine" + std::to_string(i), "D" + std::to_string(j) + "-MaxBonusDura", Drop->MaxBonusDura);
            }
        }

        delete reader;
    }

    void Settings::LoadGuildSettings()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "GuildSettings.ini")))
        {
            GuildItemVolume *tempVar = new GuildItemVolume();
            tempVar->Amount = 1000000;
            Guild_CreationCostList.push_back(tempVar);
            GuildItemVolume *tempVar2 = new GuildItemVolume();
            tempVar2->ItemName = "WoomaHorn";
            tempVar2->Amount = 1;
            Guild_CreationCostList.push_back(tempVar2);

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar2' statement was not added since tempVar2 was passed to a method or constructor. Handle memory management manually.
//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar' statement was not added since tempVar was passed to a method or constructor. Handle memory management manually.
            return;
        }
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "GuildSettings.ini"));
        Guild_RequiredLevel = reader->ReadByte("Guilds", "MinimumLevel", Guild_RequiredLevel);
        Guild_ExpRate = reader->ReadFloat("Guilds", "ExpRate", Guild_ExpRate);
        Guild_PointPerLevel = reader->ReadByte("Guilds", "PointPerLevel", Guild_PointPerLevel);
        Guild_WarTime = reader->ReadInt64("Guilds", "WarTime", Guild_WarTime);
        Guild_WarCost = reader->ReadUInt32("Guilds", "WarCost", Guild_WarCost);

        int i = 0;
        while (reader->ReadUInt32("Required-" + std::to_string(i),"Amount",0) != 0)
        {
            GuildItemVolume *tempVar3 = new GuildItemVolume();
            tempVar3->ItemName = reader->ReadString("Required-" + std::to_string(i), "ItemName", "");
            tempVar3->Amount = reader->ReadUInt32("Required-" + std::to_string(i), "Amount", 0);
            Guild_CreationCostList.push_back(tempVar3);
            i++;

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar3' statement was not added since tempVar3 was passed to a method or constructor. Handle memory management manually.
        }
        i = 0;
        while (reader->ReadInt64("Exp", "Level-" + std::to_string(i), -1) != -1)
        {
            Guild_ExperienceList.push_back(reader->ReadInt64("Exp", "Level-" + std::to_string(i), 0));
            i++;
        }
        i = 0;
        while (reader->ReadInt32("Cap", "Level-" + std::to_string(i), -1) != -1)
        {
            Guild_MembercapList.push_back(reader->ReadInt32("Cap", "Level-" + std::to_string(i), 0));
            i++;
        }
        unsigned char TotalBuffs = reader->ReadByte("Guilds", "TotalBuffs", 0);
        for (i = 0; i < TotalBuffs; i++)
        {
            GuildBuffInfo tempVar4(reader, i);
            Guild_BuffList.push_back(&tempVar4);
        }



//C# TO C++ CONVERTER TODO TASK: A 'delete reader' statement was not added since reader was passed to a method or constructor. Handle memory management manually.
    }

    void Settings::SaveGuildSettings()
    {
        File::Delete(FileSystem::combine(ConfigPath, "GuildSettings.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "GuildSettings.ini"));
        reader->Write("Guilds", "MinimumLevel", Guild_RequiredLevel);
        reader->Write("Guilds", "ExpRate", Guild_ExpRate);
        reader->Write("Guilds", "PointPerLevel", Guild_PointPerLevel);
        reader->Write("Guilds", "TotalBuffs", Guild_BuffList.size());
        reader->Write("Guilds", "WarTime", Guild_WarTime);
        reader->Write("Guilds", "WarCost", Guild_WarCost);

        int i;
        for (i = 0; i < Guild_ExperienceList.size(); i++)
        {
            reader->Write("Exp", "Level-" + std::to_string(i), Guild_ExperienceList[i]);
        }
        for (i = 0; i < Guild_MembercapList.size(); i++)
        {
            reader->Write("Cap", "Level-" + std::to_string(i), Guild_MembercapList[i]);
        }
        for (i = 0; i < Guild_CreationCostList.size(); i++)
        {
            reader->Write("Required-" + std::to_string(i), "ItemName", Guild_CreationCostList[i]->ItemName);
            reader->Write("Required-" + std::to_string(i), "Amount", Guild_CreationCostList[i]->Amount);
        }
        for (i = 0; i < Guild_BuffList.size(); i++)
        {
            Guild_BuffList[i]->Save(reader, i);
        }

//C# TO C++ CONVERTER TODO TASK: A 'delete reader' statement was not added since reader was passed to a method or constructor. Handle memory management manually.
    }

    void Settings::LinkGuildCreationItems(std::vector<ItemInfo*> &ItemList)
    {
        for (int i = 0; i < Guild_CreationCostList.size(); i++)
        {
            if (Guild_CreationCostList[i]->ItemName != "")
            {
                for (int j = 0; j < ItemList.size(); j++)
                {
//C# TO C++ CONVERTER TODO TASK: The following System.String compare method is not converted:
                    if (std::string::Compare(StringHelper::replace(ItemList[j]->Name, " ", ""), Guild_CreationCostList[i]->ItemName, StringComparison::OrdinalIgnoreCase) != 0)
                    {
                        continue;
                    }
                    Guild_CreationCostList[i]->Item = ItemList[j];
                    break;
                }
            }

        }
    }

    void Settings::LoadAwakeAttribute()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "AwakeningSystem.ini")))
        {
            return;
        }

        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "AwakeningSystem.ini"));
        Awake::AwakeSuccessRate = reader->ReadByte("Attribute", "SuccessRate", Awake::AwakeSuccessRate);
        Awake::AwakeHitRate = reader->ReadByte("Attribute", "HitRate", Awake::AwakeHitRate);
        Awake::MaxAwakeLevel = reader->ReadInt32("Attribute", "MaxUpgradeLevel", Awake::MaxAwakeLevel);
        Awake::Awake_WeaponRate = reader->ReadByte("IncreaseValue", "WeaponValue", Awake::Awake_WeaponRate);
        Awake::Awake_HelmetRate = reader->ReadByte("IncreaseValue", "HelmetValue", Awake::Awake_HelmetRate);
        Awake::Awake_ArmorRate = reader->ReadByte("IncreaseValue", "ArmorValue", Awake::Awake_ArmorRate);

        for (int i = 0; i < 4; i++)
        {
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
            Awake::AwakeChanceMax[i] = reader->ReadByte("Value", "ChanceMax_" + (static_cast<ItemGrade>(i + 1)).ToString(), Awake::AwakeChanceMax[i]);
        }

        for (int i = 0; i < static_cast<int>(AwakeType::HPMP); i++)
        {
            std::vector<std::vector<unsigned char>> value(2);

            for (int k = 0; k < 2; k++)
            {
                value[k] = std::vector<unsigned char>();
            }

            for (int j = 0; j < 4; j++)
            {
                unsigned char material1 = 1;
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                material1 = reader->ReadByte("Materials_BaseValue", (static_cast<AwakeType>(i + 1)).ToString() + "_" + (static_cast<ItemGrade>(j + 1)).ToString() + "_Material1", material1);
                unsigned char material2 = 1;
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                material2 = reader->ReadByte("Materials_BaseValue", (static_cast<AwakeType>(i + 1)).ToString() + "_" + (static_cast<ItemGrade>(j + 1)).ToString() + "_Material2", material2);
                value[0].push_back(material1);
                value[1].push_back(material2);
            }

            Awake::AwakeMaterials.push_back(value);
        }

        for (int c = 0; c < 4; c++)
        {
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
            Awake::AwakeMaterialRate[c] = reader->ReadFloat("Materials_IncreaseValue", "Materials_" + (static_cast<ItemGrade>(c + 1)).ToString(), Awake::AwakeMaterialRate[c]);
        }

        delete reader;
    }

    void Settings::SaveAwakeAttribute()
    {
        File::Delete(FileSystem::combine(ConfigPath, "AwakeningSystem.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "AwakeningSystem.ini"));
        reader->Write("Attribute", "SuccessRate", Awake::AwakeSuccessRate);
        reader->Write("Attribute", "HitRate", Awake::AwakeHitRate);
        reader->Write("Attribute", "MaxUpgradeLevel", Awake::MaxAwakeLevel);

        reader->Write("IncreaseValue", "WeaponValue", Awake::Awake_WeaponRate);
        reader->Write("IncreaseValue", "HelmetValue", Awake::Awake_HelmetRate);
        reader->Write("IncreaseValue", "ArmorValue", Awake::Awake_ArmorRate);

        for (int i = 0; i < 4; i++)
        {
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
            reader->Write("Value", "ChanceMax_" + (static_cast<ItemGrade>(i + 1)).ToString(), Awake::AwakeChanceMax[i]);
        }

        if (Awake::AwakeMaterials.empty())
        {
            for (int i = 0; i < static_cast<int>(AwakeType::HPMP); i++)
            {
                for (int j = 0; j < 4; j++)
                {
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                    reader->Write("Materials_BaseValue", (static_cast<AwakeType>(i + 1)).ToString() + "_" + (static_cast<ItemGrade>(j + 1)).ToString() + "_Material1", 1);
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                    reader->Write("Materials_BaseValue", (static_cast<AwakeType>(i + 1)).ToString() + "_" + (static_cast<ItemGrade>(j + 1)).ToString() + "_Material2", 1);
                }
            }
        }
        else
        {
            for (int i = 0; i < static_cast<int>(AwakeType::HPMP); i++)
            {
                std::vector<std::vector<unsigned char>> value = Awake::AwakeMaterials[i];

                for (int j = 0; j < value[0].size(); j++)
                {
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                    reader->Write("Materials_BaseValue", (static_cast<AwakeType>(i + 1)).ToString() + "_" + (static_cast<ItemGrade>(j + 1)).ToString() + "_Material1", value[0][j]);
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
                    reader->Write("Materials_BaseValue", (static_cast<AwakeType>(i + 1)).ToString() + "_" + (static_cast<ItemGrade>(j + 1)).ToString() + "_Material2", value[1][j]);
                }

                Awake::AwakeMaterials.push_back(value);
            }
        }

        for (int c = 0; c < 4; c++)
        {
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to 'ToString':
            reader->Write("Materials_IncreaseValue", "Materials_" + (static_cast<ItemGrade>(c + 1)).ToString(), Awake::AwakeMaterialRate[c]);
        }

        delete reader;
    }

    void Settings::LoadFishing()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "FishingSystem.ini")))
        {
            SaveFishing();
            return;
        }

        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "FishingSystem.ini"));
        FishingAttempts = reader->ReadInt32("Rates", "Attempts", FishingAttempts);
        FishingSuccessStart = reader->ReadInt32("Rates", "SuccessStart", FishingSuccessStart);
        FishingSuccessMultiplier = reader->ReadInt32("Rates", "SuccessMultiplier", FishingSuccessMultiplier);
        FishingDelay = reader->ReadInt64("Rates", "Delay", FishingDelay);
        FishingMobSpawnChance = reader->ReadInt32("Rates", "MonsterSpawnChance", FishingMobSpawnChance);
        FishingMonster = reader->ReadString("Game", "Monster", FishingMonster);

        delete reader;
    }

    void Settings::SaveFishing()
    {
        File::Delete(FileSystem::combine(ConfigPath, "FishingSystem.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "FishingSystem.ini"));
        reader->Write("Rates", "Attempts", FishingAttempts);
        reader->Write("Rates", "SuccessStart", FishingSuccessStart);
        reader->Write("Rates", "SuccessMultiplier", FishingSuccessMultiplier);
        reader->Write("Rates", "Delay", FishingDelay);
        reader->Write("Rates", "MonsterSpawnChance", FishingMobSpawnChance);
        reader->Write("Game", "Monster", FishingMonster);

        delete reader;
    }

    void Settings::LoadMail()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "MailSystem.ini")))
        {
            SaveMail();
            return;
        }

        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "MailSystem.ini"));
        MailAutoSendGold = reader->ReadBoolean("AutoSend", "Gold", MailAutoSendGold);
        MailAutoSendItems = reader->ReadBoolean("AutoSend", "Items", MailAutoSendItems);
        MailFreeWithStamp = reader->ReadBoolean("Rates", "FreeWithStamp", MailFreeWithStamp);
        MailCostPer1KGold = reader->ReadUInt32("Rates", "CostPer1k", MailCostPer1KGold);
        MailItemInsurancePercentage = reader->ReadUInt32("Rates", "InsurancePerItem", MailItemInsurancePercentage);
        MailCapacity = reader->ReadUInt32("General", "MailCapacity", MailCapacity);

        delete reader;
    }

    void Settings::SaveMail()
    {
        File::Delete(FileSystem::combine(ConfigPath, "MailSystem.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "MailSystem.ini"));
        reader->Write("AutoSend", "Gold", MailAutoSendGold);
        reader->Write("AutoSend", "Items", MailAutoSendItems);
        reader->Write("Rates", "FreeWithStamp", MailFreeWithStamp);
        reader->Write("Rates", "CostPer1k", MailCostPer1KGold);
        reader->Write("Rates", "InsurancePerItem", MailItemInsurancePercentage);
        reader->Write("General", "MailCapacity", MailCapacity);

        delete reader;
    }

    void Settings::LoadRefine()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "RefineSystem.ini")))
        {
            SaveRefine();
            return;
        }

        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "RefineSystem.ini"));
        OnlyRefineWeapon = reader->ReadBoolean("Config", "OnlyRefineWeapon", OnlyRefineWeapon);
        RefineBaseChance = reader->ReadByte("Config", "BaseChance", RefineBaseChance);
        RefineTime = reader->ReadInt32("Config", "Time", RefineTime);
        RefineIncrease = reader->ReadByte("Config", "StatIncrease", RefineIncrease);
        RefineCritChance = reader->ReadByte("Config", "CritChance", RefineCritChance);
        RefineCritIncrease = reader->ReadByte("Config", "CritIncrease", RefineCritIncrease);
        RefineWepStatReduce = reader->ReadByte("Config", "WepStatReducedChance", RefineWepStatReduce);
        RefineItemStatReduce = reader->ReadByte("Config", "ItemStatReducedChance", RefineItemStatReduce);
        RefineCost = reader->ReadInt32("Config", "RefineCost", RefineCost);

        RefineOreName = reader->ReadString("Ore", "OreName", RefineOreName);

        delete reader;
    }

    void Settings::SaveRefine()
    {
        File::Delete(FileSystem::combine(ConfigPath, "RefineSystem.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "RefineSystem.ini"));
        reader->Write("Config", "OnlyRefineWeapon", OnlyRefineWeapon);
        reader->Write("Config", "BaseChance", RefineBaseChance);
        reader->Write("Config", "Time", RefineTime);
        reader->Write("Config", "StatIncrease", RefineIncrease);
        reader->Write("Config", "CritChance", RefineCritChance);
        reader->Write("Config", "CritIncrease", RefineCritIncrease);
        reader->Write("Config", "WepStatReducedChance", RefineWepStatReduce);
        reader->Write("Config", "ItemStatReducedChance", RefineItemStatReduce);
        reader->Write("Config", "RefineCost", RefineCost);

        reader->Write("Ore", "OreName", RefineOreName);

        delete reader;
    }

    void Settings::LoadMarriage()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "MarriageSystem.ini")))
        {
            SaveMarriage();
            return;
        }
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "MarriageSystem.ini"));
        LoverEXPBonus = reader->ReadInt32("Config", "EXPBonus", LoverEXPBonus);
        MarriageCooldown = reader->ReadInt32("Config", "MarriageCooldown", MarriageCooldown);
        WeddingRingRecall = reader->ReadBoolean("Config", "AllowLoverRecall", WeddingRingRecall);
        MarriageLevelRequired = reader->ReadInt32("Config", "MinimumLevel", MarriageLevelRequired);
        ReplaceWedRingCost = reader->ReadInt32("Config", "ReplaceRingCost", ReplaceWedRingCost);

        delete reader;
    }

    void Settings::SaveMarriage()
    {
        File::Delete(FileSystem::combine(ConfigPath, "MarriageSystem.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "MarriageSystem.ini"));
        reader->Write("Config", "EXPBonus", LoverEXPBonus);
        reader->Write("Config", "MarriageCooldown", MarriageCooldown);
        reader->Write("Config", "AllowLoverRecall", WeddingRingRecall);
        reader->Write("Config", "MinimumLevel", MarriageLevelRequired);
        reader->Write("Config", "ReplaceRingCost", ReplaceWedRingCost);

        delete reader;
    }

    void Settings::LoadMentor()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "MentorSystem.ini")))
        {
            SaveMentor();
            return;
        }
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "MentorSystem.ini"));
        MentorLevelGap = reader->ReadByte("Config", "LevelGap", MentorLevelGap);
        MentorSkillBoost = reader->ReadBoolean("Config", "MenteeSkillBoost", MentorSkillBoost);
        MentorLength = reader->ReadByte("Config", "MentorshipLength", MentorLength);
        MentorDamageBoost = reader->ReadByte("Config", "MentorDamageBoost", MentorDamageBoost);
        MentorExpBoost = reader->ReadByte("Config", "MenteeExpBoost", MentorExpBoost);
        MenteeExpBank = reader->ReadByte("Config", "PercentXPtoMentor", MenteeExpBank);

        delete reader;
    }

    void Settings::SaveMentor()
    {
        File::Delete(FileSystem::combine(ConfigPath, "MentorSystem.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "MentorSystem.ini"));
        reader->Write("Config", "LevelGap", MentorLevelGap);
        reader->Write("Config", "MenteeSkillBoost", MentorSkillBoost);
        reader->Write("Config", "MentorshipLength", MentorLength);
        reader->Write("Config", "MentorDamageBoost", MentorDamageBoost);
        reader->Write("Config", "MenteeExpBoost", MentorExpBoost);
        reader->Write("Config", "PercentXPtoMentor", MenteeExpBank);

        delete reader;
    }

    void Settings::LoadGem()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "GemSystem.ini")))
        {
            SaveGem();
            return;
        }
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "GemSystem.ini"));
        GemStatIndependent = reader->ReadBoolean("Config", "GemStatIndependent", GemStatIndependent);


        delete reader;
    }

    void Settings::SaveGem()
    {
        File::Delete(FileSystem::combine(ConfigPath, "GemSystem.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "GemSystem.ini"));
        reader->Write("Config", "GemStatIndependent", GemStatIndependent);

        delete reader;
    }

    void Settings::LoadGoods()
    {
        if (!FileSystem::fileExists(FileSystem::combine(ConfigPath, "GoodsSystem.ini")))
        {
            SaveGoods();
            return;
        }

        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "GoodsSystem.ini"));
        GoodsOn = reader->ReadBoolean("Goods", "On", GoodsOn);
        GoodsMaxStored = reader->ReadUInt32("Goods", "MaxStored", GoodsMaxStored);
        GoodsBuyBackTime = reader->ReadUInt32("Goods", "BuyBackTime", GoodsBuyBackTime);
        GoodsBuyBackMaxStored = reader->ReadUInt32("Goods", "BuyBackMaxStored", GoodsBuyBackMaxStored);
        GoodsHideAddedStats = reader->ReadBoolean("Goods", "HideAddedStats", GoodsHideAddedStats);

        delete reader;
    }

    void Settings::SaveGoods()
    {
        File::Delete(FileSystem::combine(ConfigPath, "GoodsSystem.ini"));
        InIReader *reader = new InIReader(FileSystem::combine(ConfigPath, "GoodsSystem.ini"));
        reader->Write("Goods", "On", GoodsOn);
        reader->Write("Goods", "MaxStored", GoodsMaxStored);
        reader->Write("Goods", "BuyBackTime", GoodsBuyBackTime);
        reader->Write("Goods", "BuyBackMaxStored", GoodsBuyBackMaxStored);
        reader->Write("Goods", "HideAddedStats", GoodsHideAddedStats);

        delete reader;
    }
}
